package net.jueb.sniff4j.extr.filter;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import net.jueb.sniff4j.extr.base.AbstractRuntime;
import net.jueb.sniff4j.extr.base.ServerContext;
import net.jueb.sniff4j.extr.base.UserContext;
import net.jueb.sniff4j.extr.filter.blocker.Blocker;
import net.jueb.sniff4j.extr.filter.builder.RBuilder;
import net.jueb.sniff4j.extr.util.BytesUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.UnpooledUnsafeDirectByteBuf;
import io.netty.channel.Channel;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;

/**
 * 对象过滤器
 * 客户端请求数据==>通道过滤器(filter)-->阻塞通道-->重建通道==>服务端
 * 过滤情况三种：
 * 1.数据顺利到达(可能被重建)
 * 2.数据未到达(被阻断)
 * 3.数据未到达且有逆向返回数据(被阻断并向来源回复数据)
 * 如果没有被阻塞，则会执行重建通道
 * 不同的数据方向，具有不同的阻塞和重建器
 * 该过滤器的具体实现类需要在User和Runtime设置正确的对应通道
 * 比如：
 * 	@Override
	public AbstractObjectFilter getSendToClientFilter(Channel fromChannel,
			Channel toChannel, AbstractRuntime runtime) {
		return new HttpResponseFilter(fromChannel, toChannel, runtime);
	}

	@Override
	public AbstractObjectFilter getSendToTargetFilter(Channel fromChannel,
			Channel toChannel, AbstractRuntime runtime) {
		return new HttpRequestFilter(fromChannel, toChannel, runtime);
	}
 * @author Administrator
 */
public class DefaultObjectFilter {
	protected static final InternalLogger log = InternalLoggerFactory.getInstance(DefaultObjectFilter.class);
	
	protected boolean showFilteInfo=false;
	private final Channel fromChannel;
	private final Channel toChannel;
	private final AbstractRuntime runtime;
	private final ServerContext serverContext;
	private final UserContext userContext;
	
	
	
	/**
	 * 阻塞器队列
	 */
	private final LinkedHashMap<String,Blocker> blockers=new LinkedHashMap<String,Blocker>();
	
	/**
	 * 重建器队列
	 */
	private final LinkedHashMap<String, RBuilder> rebuilders=new LinkedHashMap<String,RBuilder>();

	
	/**
	 * 子类必须初始化该参数对象
	 * @param fromChannel
	 * @param toChannel
	 * @param runtime
	 */
	public DefaultObjectFilter(Channel fromChannel, Channel toChannel,AbstractRuntime runtime) {
		super();
		this.fromChannel = fromChannel;
		this.toChannel = toChannel;
		this.runtime = runtime;
		this.serverContext=this.runtime.getServerConext();
		this.userContext=findUserContext();
		initBlockers(blockers);
		initRebuilders(rebuilders);
	}
	private UserContext findUserContext()
	{
		UserContext ctx=null;
		ctx=this.runtime.getCurrentUserContext(fromChannel);
		if(ctx==null)
		{
			ctx=this.runtime.getCurrentUserContext(toChannel);
		}
		return ctx;
	}

	/**
	 * 如果返回null,则表示不会对象不允许传递
	 * 接口方法，不允许子类修改
	 * @param requestOrResponse 过滤对象
	 * @param fromChannel 对象来自通道
	 * @param toChannel 对象要到达的通道
	 * @return
	 */
	public final  Object doFilt(final Object requestOrResponse)
	{
		if(showFilteInfo)
		{
			showFiltTargetInfo(requestOrResponse);//调用对象展示方法
		}
		Object target=crossBlockers(blockers, requestOrResponse);
		if(target==null)
		{//数据被拦截
			return null;
		}
		target=crossRebuilders(rebuilders, target);
		if(target==null)
		{//数据重建错误
			return null;
		}
		return target;
	}
	
	/**
	 * 添加阻断器
	 * @param name
	 * @param blocker
	 */
	public final void addBlocker(String name,Blocker blocker)
	{
		this.blockers.put(name, blocker);
	}
	/**
	 * 添加重建器
	 * @param name
	 * @param rebuilder
	 */
	public final void addRbuilder(String name,RBuilder rebuilder)
	{
		this.rebuilders.put(name, rebuilder);
	}
	
	/**
	 * 获取过滤对象的来自通道
	 * @return
	 */
	protected final Channel getFromChannel()
	{
		return this.fromChannel;
	}
	/**
	 * 获取过滤对象的目的通道
	 * @return
	 */
	protected final Channel getToChannel()
	{
		return this.toChannel;
	}
	
	protected final AbstractRuntime getRuntime()
	{
		return this.runtime;
	}
	protected final ServerContext getServerContext()
	{
		return this.serverContext;
	}
	protected final UserContext getUserContext() {
		return userContext;
	}
	/**
	 * 获取通过阻断器集合后的对象
	 * @param blockers
	 * @param blockTarget
	 * @return 返回null表示未被拦截
	 */
	protected final Object crossBlockers(LinkedHashMap<String,Blocker> blockers,Object blockTarget)
	{
		Object target=blockTarget;
		for(Iterator<Entry<String, Blocker>> it = blockers.entrySet().iterator();it.hasNext();)
		{  
            Entry<String, Blocker> entry = it.next();
            Blocker blocker=entry.getValue();
            target=blocker.cross(target);//通过一个阻断器
            if(target!=null)
			{//未被阻断拦截，继续下一个阻断
            	continue;
			}else
			{//如果被终止，则退出循环
				break;
			}
        }  
		return target;
	}
	/**
	 * 
	 * @param rebuilders 重建器集合
	 * @param rebuildTarget 重建对象
	 * @return 返回null则表示没有被重建
	 */
	protected final Object crossRebuilders(LinkedHashMap<String, RBuilder> rebuilders,Object rebuildTarget)
	{
		Object target=rebuildTarget;
		for(Iterator<Entry<String,RBuilder>> it = rebuilders.entrySet().iterator();it.hasNext();)
		{  
            Entry<String,RBuilder> entry = it.next();
            RBuilder rb=entry.getValue();
            target=rb.cross(target);//让目标通过重建器
			if(target!=null)
			{//如果被重建
				if(rb.isFinallRebuild())
				{//如果是最终重建，则不进行后续重建
					break;
				}else
				{
					continue;
				}
			}else
			{//如果为null则终止
				return null;
			}
		}
		return target;
	}
	
	/**
	 * 初始化阻断器集合
	 * @param blockers
	 */
	protected void initBlockers(LinkedHashMap<String,Blocker> blockers)
	{
		
	}
	/**
	 * 执行阻断过程之前对过滤目标的操作
	 * @param filtTarget
	 * @return 返回新的过滤目标
	 */
	protected Object crossBlockersBefore(final Object filtTarget)
	{
		return filtTarget;
	}
	/**
	 * 执行阻断过程之后对过滤目标的操作
	 * @param filtTarget
	 * @return 返回新的过滤目标
	 */
	protected Object crossBlockersAfter(final Object filtTarget)
	{
		return filtTarget;
	}
	/**
	 * 初始化重建器集合
	 * @param rebuilders
	 */
	protected void initRebuilders(LinkedHashMap<String, RBuilder> rebuilders)
	{
		
	}
	/**
	 * 执行重建过程之前对过滤目标的操作
	 * @param filtTarget
	 * @return 返回新的过滤目标
	 */
	protected Object crossRebuildersBefore(final Object filtTarget)
	{
		return filtTarget;
	}
	/**
	 * 执行重建过程之后对过滤目标的操作
	 * @param filtTarget
	 * @return 返回新的过滤目标
	 */
	protected Object crossRebuildersAfter(final Object filtTarget)
	{
		return filtTarget;
	};
	
	/**
	 * 返回十六进制字符串格式
	 * @param buf
	 * @return
	 */
	protected String hexDump(ByteBuf buf)
	{
		buf.markReaderIndex();//标记读取前的位置
		int length=buf.readableBytes();
		byte[] data=new byte[length];
		ByteBufInputStream bis=new ByteBufInputStream(buf, length);
		try {
			bis.readFully(data);//读取所有数据到data里面
			bis.close();
		} catch (IOException e) {
		}
		return length+"Bytes:\n"+BytesUtil.printBytes(data);
	}
	/**
	 * 展示过滤目标
	 */
	protected  void showFiltTargetInfo(final Object filtTarget)
	{
		String userNmae=getUserContext().getUser().getName();
		String from=getFromChannel().remoteAddress().toString();
		String to=getToChannel().remoteAddress().toString();
		String info=userNmae+"{"+from+"=>"+to+"}:\n";
		if(filtTarget instanceof UnpooledUnsafeDirectByteBuf)
		{
			UnpooledUnsafeDirectByteBuf buf=(UnpooledUnsafeDirectByteBuf)filtTarget;
			log.debug("DefaultObjectFilter==>showFiltTargetInfo:+\n"+info+hexDump(buf));
			buf.resetReaderIndex();//复位读取位置
		}else
		{
			log.debug(info+filtTarget.toString());
		}
	}
	public boolean isShowFilteInfo() {
		return showFilteInfo;
	}
	
}
